package cn.shengchao.examstar.product.ohs.remote.rpc;

import cn.shengchao.base.utils.SpringContextHolder;
import cn.shengchao.examstar.knowledge.domain.entity.KnowledgePoint;
import cn.shengchao.examstar.rpc.product.req.SaveCourseNodes;
import com.baomidou.mybatisplus.core.incrementer.IdentifierGenerator;

import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

public class CourseNodeBuilder {

    private static IdentifierGenerator idGenerator = SpringContextHolder.getBean(IdentifierGenerator.class);

    private static final int SORT_STEP = 1000;

    /**
     * 从知识点列表中找到指定 path 的根节点，并从该点构建 SaveCourseNodes 树
     */
    public static List<SaveCourseNodes> fromKnowledgePoints(
            List<KnowledgePoint> kps, Long courseId, String rootPath) {

        // 1. 找出指定 path 的根节点（可能为多个）
        List<KnowledgePoint> roots = kps.stream()
                .filter(kp -> rootPath.startsWith(kp.getPath())) // 假设用 description 来表示 path
                .toList();

        if (roots.isEmpty()) {
            throw new RuntimeException("必须选择父节点!");
        }
        // 2. 为每个知识点生成分布式 ID，并记录对应关系
        Map<Long, Long> kpIdToGeneratedId = new HashMap<>();
        for (KnowledgePoint kp : kps) {
            kpIdToGeneratedId.put(kp.getId(), idGenerator.nextId(null).longValue());
        }

        // 3. 构建 parentId → children 映射
        Map<Long, List<KnowledgePoint>> byParent = kps.stream()
                .collect(Collectors.groupingBy(kp -> kp.getParentId() == null ? 0L : kp.getParentId()));

        // 4. 构建树结构
        AtomicInteger sortIndex = new AtomicInteger(0);
        List<SaveCourseNodes> result = new ArrayList<>();
        for (KnowledgePoint root : roots) {
            SaveCourseNodes rootNode = toCourseNode(root, courseId, kpIdToGeneratedId, sortIndex.getAndAdd(SORT_STEP));
            rootNode.setParentId(0L); // 顶级节点没有父
            rootNode.setIsLesson(0L);
            rootNode.setSort(sortIndex.getAndAdd(SORT_STEP));
            rootNode.setChildren(buildLevel(root.getId(), byParent, kpIdToGeneratedId, courseId, sortIndex));
            if (rootNode.getChildren() == null || rootNode.getChildren().isEmpty()) {
                //如果没有子结点,变成叶子
                rootNode.setIsLesson(1L);
                rootNode.setPrice(BigDecimal.valueOf(2));
                rootNode.setDiscountPrice(BigDecimal.valueOf(1));
                rootNode.setKnowledgePointIds(Collections.singletonList(root.getId()));
            }
            result.add(rootNode);
        }
        return result;
    }

    private static List<SaveCourseNodes> buildLevel(
            Long parentKpId,
            Map<Long, List<KnowledgePoint>> byParent,
            Map<Long, Long> kpIdToGeneratedId,
            Long courseId, AtomicInteger sortIndex) {

        List<SaveCourseNodes> nodes = new ArrayList<>();
        List<KnowledgePoint> children = byParent.getOrDefault(parentKpId, new ArrayList<>());

        for (KnowledgePoint kp : children) {
            SaveCourseNodes node = toCourseNode(kp, courseId, kpIdToGeneratedId, sortIndex.getAndAdd(SORT_STEP));
            node.setParentId(kpIdToGeneratedId.get(kp.getParentId()));
            // 判断是否为叶子节点：没有子知识点就是叶子
            boolean isLeaf = !byParent.containsKey(kp.getId());
            node.setIsLesson(isLeaf ? 1L : 0L);
            node.setChildren(buildLevel(kp.getId(), byParent, kpIdToGeneratedId, courseId, sortIndex));
            nodes.add(node);
        }

        return nodes;
    }


    /**
     * KnowledgePoint 转换为 SaveCourseNodes
     */
    private static SaveCourseNodes toCourseNode(KnowledgePoint kp, Long courseId, Map<Long, Long> kpIdToGeneratedId, int sortIndex) {
        SaveCourseNodes node = new SaveCourseNodes();
        node.setId(kpIdToGeneratedId.get(kp.getId()));
        node.setCourseId(courseId);
        node.setName(kp.getName());
        node.setSort(sortIndex);
        node.setPrice(BigDecimal.valueOf(2));
        node.setDiscountPrice(BigDecimal.valueOf(1));
        node.setIsLesson(1L);
        node.setKnowledgePointIds(Collections.singletonList(kp.getId()));
        node.setChildren(new ArrayList<>());
        return node;
    }
}
